package algorithms;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import datastructures.INode;

/**
 * @author Yuval Kesten
 *         <ul>
 *         Most naive implementation of Item Set Counting. Since this algorithm
 *         expands all subsets it can only run on small input mainly for sanity
 *         checks purposes
 *         </ul>
 */
public class StraightForwardAlgo extends Algo {

	public HashMap<String, Integer> histogram;

	public StraightForwardAlgo(String pathFormat, int startIndex, int endIndex) throws Exception {
		super(pathFormat, startIndex, endIndex);
		histogram = new HashMap<String, Integer>();
	}

	public StraightForwardAlgo(String pathFormat, int startIndex, int endIndex, Set<String> alphabetSet) {
		super(pathFormat, startIndex, endIndex, alphabetSet);
		histogram = new HashMap<String, Integer>();
	}

	public List<String> findFrequentItemSet(double support, int maxK) throws Exception {

		BufferedReader br;
		FileReader fr;
		String line;
		String[] tmpBasket;
		LinkedList<String> result = new LinkedList<String>();

		iterNum++;

		numOfItems = 0;
		numOfBaskets = 0;
		for (int i = fileStartIndex; i <= fileEndIndex; i++) {
			fr = new FileReader(String.format(filePathFormat, i));
			br = new BufferedReader(fr);
			while ((line = br.readLine()) != null) {
				if (line.startsWith("#") || line.equals(""))
					// Ignore comments
					continue;
				else {
					tmpBasket = Common.parseLineToBasket(line);
					numOfItems += tmpBasket.length;
					numOfBaskets++;
					newBasket(tmpBasket, maxK);
				}
			}
			br.close();
			fr.close();
		}

		for (String string : histogram.keySet()) {
			int val = histogram.get(string);
			if (val > support * numOfBaskets)
				result.add(string);
		}

		return result;
	}

	protected void newBasket(String[] tmpBasket, int maxK) {
		Arrays.sort(tmpBasket);
		String subsetStr;

		List<List<String>> subsets = Common.getSubsetsOfSize(tmpBasket, 1, getAlphabet());

		for (int i = 2; i <= maxK; i++) {
			List<List<String>> tmp = Common.getSubsetsOfSize(tmpBasket, i, getAlphabet());
			if (tmp == null)
				break;
			subsets.addAll(tmp);
		}
		if (subsets == null)
			return;
		for (List<String> list : subsets) {
			subsetStr = list.toString();
			if (histogram.containsKey(subsetStr))
				histogram.put(subsetStr, histogram.get(subsetStr) + 1);
			else
				histogram.put(subsetStr, 1);
		}
	}

	/***************** Stubs ****************************************************/
	@Override
	public INode findFrequentItemSet(double support, int minimumK, int maxK) {
		return null;
	}

	@Override
	protected boolean endOfSingleIteration(double support, long basketIndex, boolean foundSomething) {
		return false;
	}

	@Override
	protected void init() {
	}

	@Override
	protected boolean processSingleLine(String line, double support) {
		return true;
	}

	@Override
	protected void startOfSingleIteration() {
	}
}
